package com.board.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.board.client.StoreServiceClient;
import com.board.client.dto.StoreDto;
import com.board.dao.OrderDetailMapper;
import com.board.dao.OrderLogMapper;
import com.board.dao.SendOrderMapper;
import com.board.dto.*;
import com.board.entity.OrderDetail;
import com.board.entity.OrderLog;
import com.board.entity.SeatEatOrder;
import com.board.entity.SendOrder;
import com.board.exception.SeatOrderException;
import com.board.param.StoreOutSendOrderParam;
import com.board.param.UserFindSeatOrderParam;
import com.board.service.SendOrderService;
import com.board.util.StateDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 膳食系统-派送订单表 服务实现类
 * </p>
 *
 * @author 小叶
 * @since 2024年04月04日
 */
@Service
public class SendOrderServiceImpl extends ServiceImpl<SendOrderMapper, SendOrder> implements SendOrderService {
    @Autowired
    private SendOrderMapper sendOrderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private StoreServiceClient storeServiceClient;
    @Autowired
    private OrderLogMapper orderLogMapper;

    @Override
    public List<SendOrderDto> userFindOrder(UserFindSeatOrderParam param, Integer userId) {
        QueryWrapper<SendOrder> orderWrapper = new QueryWrapper<>();
        QueryWrapper<OrderDetail> detailWrapper = new QueryWrapper<>();
        orderWrapper.eq("user_id",userId);
        //先只从订单表里面查询,判断是否传递时间段
        if (param.getTimeChose()!=null){
            if (param.getTimeChose()!=0&&param.getTimeChose()!=1){
                throw new SeatOrderException(500,"时间段参数错误");
            }
            if (param.getTimeChose()==0){
                //一周内
                orderWrapper.apply("date_sub(curdate(),interval 7 day) <= date(create_time)");
            }else{
                //一个月内
                orderWrapper.apply("date_sub(curdate(),interval 1 month) <= date(create_time)");
            }
        }
        List<SendOrder> seatEatOrders = sendOrderMapper.selectList(orderWrapper);
        //如果传递了食堂名称和商店名称，需要去详情表中查询，并且是在上面的订单编号中筛选
        if(param.getStoreName()!=null&&param.getStoreName()!=""){
            detailWrapper.like("store_name",param.getStoreName());
        }
        if (param.getCanteenName()!=null&&param.getCanteenName()!=""){
            detailWrapper.like("canteen_name",param.getCanteenName());
        }

        detailWrapper.in("order_num",seatEatOrders.stream().map(SendOrder::getOrderNum).collect(Collectors.toList()));
        List<OrderDetail> details = orderDetailMapper.selectList(detailWrapper);
        //上面查询回来的details才是真正所有的订单
        ArrayList<SendOrderDto> list = new ArrayList<>();
        HashMap<String, List<OrderDetail>> detailHashmap = new HashMap<>();
        for (OrderDetail detail : details) {
            if (!detailHashmap.containsKey(detail.getOrderNum())){
                ArrayList<OrderDetail> orderDetails = new ArrayList<>();
                orderDetails.add(detail);
            }else{
                List<OrderDetail> orderDetails = detailHashmap.get(detail.getOrderNum());
                orderDetails.add(detail);
            }
        }
        //循环订单表查询回来的数据，如果map中有这个订单编号，就添加到list中
        for (SendOrder seatEatOrder : seatEatOrders) {
            if (detailHashmap.containsKey(seatEatOrder.getOrderNum())){
                SendOrderDto dto = BeanUtil.toBean(seatEatOrder, SendOrderDto.class);
                List<OrderDetail> detailList = detailHashmap.get(seatEatOrder.getOrderNum());
                dto.setCanteenName(detailList.get(0).getCanteenName());
                dto.setStoreName(detailList.get(0).getStoreName());
                dto.setFoodOrderList(BeanUtil.copyToList(detailList, FoodOrderDto.class));
                dto.setOrderStateName(seatEatOrder.getOrderState()==0?"待支付":
                    seatEatOrder.getOrderState()==1?"已取消":
                    seatEatOrder.getOrderState()==2?"待接单":
                    seatEatOrder.getOrderState()==3?"商家未接单":
                    seatEatOrder.getOrderState()==4?"已接单":
                    seatEatOrder.getOrderState()==5?"已出餐":
                    seatEatOrder.getOrderState()==6?"已取餐":"已退款");

                list.add(dto);
            }
        }
        return list;

    }

    @Override
    public SendOrderOutDto storeOutSendOrder(StoreOutSendOrderParam param,Integer storeId) {
        //商家出餐订单：订单是否存在、是否是该商家的、订单状态是否正确
        QueryWrapper<OrderDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("order_num",param.getOrderNum());
        List<OrderDetail> details = orderDetailMapper.selectList(wrapper);
        if (details.size()==0) throw new SeatOrderException(500,"订单不存在");
        if (details.get(0).getStoreId()!=storeId) throw new SeatOrderException(500,"订单不属于该商家");
        //用户已支付后才能进行出餐
        SendOrder seatEatOrder = sendOrderMapper.selectById(param.getOrderNum());
        if (seatEatOrder.getOrderState()!= StateDate.SEND_ORDER_STATE_PAY){
            throw new SeatOrderException(500,"订单状态错误");
        }
        //商家可以进行出餐
        seatEatOrder.setOrderState(StateDate.SEND_ORDER_STATE_HAS_FOOD);
        seatEatOrder.setStoreOutTime(LocalDateTime.now().toString());
        seatEatOrder.setSenderName(param.getSenderName());
        seatEatOrder.setSenderPhone(param.getSenderPhone());
        sendOrderMapper.updateById(seatEatOrder);
        //返回数据
        SendOrderOutDto dto = BeanUtil.toBean(seatEatOrder, SendOrderOutDto.class);
        dto.setCanteenName(details.get(0).getCanteenName());
        dto.setStoreName(details.get(0).getStoreName());
        dto.setFoodOrderList(BeanUtil.copyToList(details, FoodOrderDto.class));
        dto.setOrderStateName("商家已出餐");
        //生成订单日志数据
        StoreDto data = storeServiceClient.findStoreById(storeId).getData();
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderType(seatEatOrder.getOrderType());
        orderLog.setOrderNum(seatEatOrder.getOrderNum());
        orderLog.setLogTime(LocalDateTime.now().toString());
        orderLog.setLogUser(data.getStoreName());
        orderLog.setLogDesc(data.getStoreName()+"出餐完成外送订单");
        orderLogMapper.insert(orderLog);
        return dto;

    }

    @Override
    public SendOrderOutDto storeConfirmOrder(String orderNum, Integer storeId) {
        //判断订单是否是该商家的
        QueryWrapper<OrderDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("order_num",orderNum);
        List<OrderDetail> details = orderDetailMapper.selectList(wrapper);
        if (details.size()==0) throw new SeatOrderException(500,"订单不存在");
        if (details.get(0).getStoreId()!=storeId) throw new SeatOrderException(500,"订单不属于该商家");
        //商家已出餐后才能进行确认送达
        SendOrder sendOrder = sendOrderMapper.selectById(orderNum);
        if (sendOrder.getOrderState()!=StateDate.SEND_ORDER_STATE_HAS_FOOD){
            throw new SeatOrderException(500,"订单状态错误");
        }
        //可以进行送达
        sendOrder.setOrderState(StateDate.SEND_ORDER_STATE_GET_FOOD);
        String time = LocalDateTime.now().toString();
        sendOrder.setSendTime(time);
        if (sendOrder.getGetTime()==null|| sendOrder.getGetTime()==""){
            //用户没有自己点送达
            sendOrder.setGetTime(time);
        }
        sendOrderMapper.updateById(sendOrder);
        SendOrderOutDto dto = BeanUtil.toBean(sendOrder, SendOrderOutDto.class);
        dto.setCanteenName(details.get(0).getCanteenName());
        dto.setStoreName(details.get(0).getStoreName());
        dto.setFoodOrderList(BeanUtil.copyToList(details, FoodOrderDto.class));
        dto.setOrderStateName("商家已送达");
        //生成订单日志数据
        StoreDto data = storeServiceClient.findStoreById(storeId).getData();
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderType(sendOrder.getOrderType());
        orderLog.setOrderNum(sendOrder.getOrderNum());
        orderLog.setLogTime(LocalDateTime.now().toString());
        orderLog.setLogUser(data.getStoreName());
        orderLog.setLogDesc(data.getStoreName()+"商家已送达外送订单");
        orderLogMapper.insert(orderLog);
        return dto;
    }
}
